package com.njxxted.activiti.modules.process.task.controller;

import com.alibaba.fastjson.JSON;
import com.njxxted.activiti.common.exception.CustomerException;
import com.njxxted.activiti.common.response.ResponseVo;
import com.njxxted.activiti.common.util.*;
import com.njxxted.activiti.modules.api.CommonApi;
import com.njxxted.activiti.modules.api.entity.FileEntity;
import com.njxxted.activiti.modules.base.controller.BaseController;
import com.njxxted.activiti.modules.process.task.service.IActTaskService;
import feign.Response;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.activiti.engine.TaskService;
import org.activiti.engine.task.Attachment;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * 描述：流程任务 controller
 * <p>
 * 作者：Ostrich Hu
 * 时间：2019/9/5 16:37 星期四
 */
@Api(tags = "流程任务")
@RestController
@RequestMapping(value = "/act/rest/task")
public class ActTaskController extends BaseController {

    @Resource
    private IActTaskService iActTaskService;

    @Resource
    private TaskService taskService;

    private FeignUtil<CommonApi> commonApiFeignUtil = new FeignUtil<>();

    @PostMapping(value = "/complete")
    @ApiOperation(value = "办理任务" , notes = "根据条件办理（完成）任务")
    public ResponseVo completeTask(HttpServletRequest request) {
        try {
            return iActTaskService.completeTask(request);
        } catch (Exception e) {
            throw new CustomerException("办理任务失败" , e);
        }
    }

    @PostMapping(value = "/nextNode")
    @ApiOperation(value = "获取流程下一节点人员信息")
    public ResponseVo getNextNodeCandidateUser(HttpServletRequest request, String type) {
        try {
            Map<String, Object> nodeCandidateUser = iActTaskService.getNextNodeCandidateUser(request, type);
            return ResponseVo.ok(nodeCandidateUser);
        } catch (Exception e) {
            throw new CustomerException("查询流程节点人员信息失败" , e);
        }
    }

    @PostMapping(value = "/attachment/{instanceId}/{taskId}")
    @ApiOperation("创建任务附件")
    public ResponseVo attachmentTask(@RequestParam("file") MultipartFile file, FileEntity fileEntity,
                                     @RequestParam(name = "path" , defaultValue = "temp") String path,
                                     @PathVariable String instanceId, @PathVariable String taskId,
                                     HttpServletRequest request) {
        try {
            StringBuilder url = new StringBuilder();
            url.append(IPUtils.getLocalURI());
            fileEntity.setIp(url.toString());
            fileEntity.setAddUser(UserUtil.userId());
            ResponseVo res = commonApiFeignUtil.invokeCommonService(CommonApi.class).uploadFile(file, fileEntity, path);
            String data = JsonUtils.beanToJson(res.get("data"));
            fileEntity = JSON.parseObject(data, FileEntity.class);
            String attachmentUrl = String.valueOf(url.append("/act/rest/task/down/").append(fileEntity.getCode()));
            String fileType = FileType.fileType(fileEntity.getName());
            Attachment attachment = taskService.createAttachment(fileType, taskId, instanceId,
                    fileEntity.getName(), fileEntity.getRemark(), attachmentUrl);
            return ResponseVo.ok(attachment);
        } catch (Exception e) {
            throw new CustomerException("创建任务{" + taskId + "}附件失败" , e);
        }
    }

    @PostMapping(value = "/attachment/taskId")
    @ApiOperation("查询某个task所关联的附件集合")
    public ResponseVo getTaskAttachments(String taskId) {
        return ResponseVo.ok(taskService.getTaskAttachments(taskId));
    }

    @PostMapping(value = "/attachment/instanceId")
    @ApiOperation("查询某个实例所关联的附件集合（多个task组合成一个实例）")
    public ResponseVo getInstanceAttachments(String processInstanceId) {
        return ResponseVo.ok(taskService.getProcessInstanceAttachments(processInstanceId));
    }

    @PostMapping(value = "/attachment/del/{attachmentId}")
    @ApiOperation("根据附件ID删除附件信息")
    public ResponseVo deleteAttachment(@PathVariable String attachmentId) {
        taskService.deleteAttachment(attachmentId);
        return ResponseVo.ok();
    }

    @ApiOperation("根据附件code下载文件")
    @GetMapping(value = "/down/{code}")
    public void fileDown(HttpServletResponse servletResponse, @PathVariable String code) {
        Response response = commonApiFeignUtil.invokeCommonService(CommonApi.class).findFileByFileCode(code);
        Response.Body body = response.body();
        Set<String> keySets = response.headers().keySet();
        keySets.forEach(key -> {
            Collection<String> kList = response.headers().get(key);
            kList.forEach(val -> servletResponse.setHeader(String.valueOf(key), val));
        });
        try (InputStream inputStream = body.asInputStream();
             OutputStream outputStream = servletResponse.getOutputStream()) {
            byte[] b = new byte[inputStream.available()];
            inputStream.read(b);
            outputStream.write(b);
            outputStream.flush();
        } catch (IOException e) {
            throw new CustomerException("IO流异常" , e);
        }
    }
}
